package yxy.game.pm2.module.gacha;

import java.util.*;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.joda.time.DateTime;
import org.redisson.api.RBucket;
import org.redisson.api.RLongAdder;
import org.redisson.api.RMap;
import yxy.apple.util.RandomUtility;
import yxy.apple.util.RandomUtility.Weight;
import yxy.apple.util.concurrent.ThreadPoolManager;
import yxy.cherry.battle.Battle;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.*;
import yxy.cherry.data.script.fomula;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.cherry.game.base.redis.RedisType;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.Hero;
import yxy.game.pm2.bean.Item;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.currency.CurrencyNotEnoughException;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.pubsub.ActivityPublisher;
import yxy.game.pm2.bean.pubsub.HeroStarPublisher;
import yxy.game.pm2.bean.task.TaskType;
import yxy.game.pm2.message.HeroMessage;
import yxy.game.pm2.message.MainMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.battle.BattleHandle;
import yxy.game.pm2.module.battle.FighterModule;
import yxy.game.pm2.module.hero.HeroHandle;
import yxy.game.pm2.module.task.TaskHandle;

public class GachaHeroHandle {
    // 新手==============================================================
    public Result summonGuide(GachaHeroModule module, int type, MainMessage.GuideGachaResponse.Builder response) throws Exception {
        String playerCode = module.getPlayerCode();
        int num = 0;
        //type: 1:高级单抽  2:高级10连抽  3:普通单抽  4:友情单抽
        switch (type) {
            case 1:
                num = 1;
                break;
            case 2:
                num = 10;
                break;
            case 3:
                num = 1;
                break;
            case 4:
                num = 1;
                break;
        }

        GachaHeroType gachaType = null;
        //类型1和2是 GachaHeroType.元宝  类型3是 GachaHeroType.普通 4是友情 ,
        switch (type) {
            case 1:
                gachaType = GachaHeroType.元宝;
                break;
            case 2:
                gachaType = GachaHeroType.元宝;
                break;
            case 3:
                gachaType = GachaHeroType.普通;
                break;
            case 4:
                gachaType = GachaHeroType.友情;
                break;
        }

        //summonCost进行资源消耗
        Result result = summonCost(module, gachaType, num, response);
        if (result != Result.Success) {
            return result;
        }

        GachaHeroBean bean = module.bean(GachaHeroType.元宝);
//		if (bean.isGachaed()) {
//			return Result.ParamError;
//		}

        guideinitial initialdata = DataCenter.getData(1, guideinitial.class);// 初始化数据集

        Set<Hero> heros = new HashSet<>();
        //固定返回对应武将
        switch (type) {
            case 1: {
                // 玩家首次元宝抽将
                int heroId = initialdata.getSingletheroid();
                Hero hero = new HeroHandle().createHero(playerCode, heroId, CCReason.招募武将);
                if (hero != null) {
                    heros.add(hero);
                }
            }
            break;
            case 2: {
                for (int i = 0; i < initialdata.getRecruitheroid().length; i++) {
                    int heroId = initialdata.getRecruitheroid()[i];
                    Hero hero = new HeroHandle().createHero(playerCode, heroId, CCReason.招募武将);
                    if (hero != null) {
                        heros.add(hero);
                    }
                }
                bean.gachaed();
                module.set();
            }
            break;
            case 3: {
                // 普通单抽
                int heroId = initialdata.getCommonheroid();
                Hero hero = new HeroHandle().createHero(playerCode, heroId, CCReason.招募武将);
                if (hero != null) {
                    heros.add(hero);
                }
            }
            break;
            case 4: {
                // 友情单抽
                int heroId = initialdata.getFriendheroid();
                Hero hero = new HeroHandle().createHero(playerCode, heroId, CCReason.招募武将);
                if (hero != null) {
                    heros.add(hero);
                }
            }
            break;
        }

        HeroHandle herosModule = new HeroHandle();
        for (Hero hero : heros) {
            response.addHeros(herosModule.getHeroSimple(playerCode, hero));
        }
        response.addAllInfo(gachaInfo(playerCode));
//		response.setType(GachaHeroType.元宝);
        return Result.Success;
    }

    private Result summonCost(GachaHeroModule module, GachaHeroType type, int num, MainMessage.GuideGachaResponse.Builder response) {
        String playerCode = module.getPlayerCode();
        // 抽将付费信息
        summonpooldate _summonpooldate = DataCenter.getData(type.getNumber(), summonpooldate.class);

        if (num == 1) {
            GachaHeroBean bean = module.bean(type);
            if (bean != null) {
                if (bean.getFreeTimes() > 0) {
                    //免费次数-1
                    bean.freeonce();
                    module.set();
                    return Result.Success;
                }
            }
        }

        // 优先消费
        ArrayList<Currency> costs = new ArrayList<>();
        Currency cost1 = Currency.create(_summonpooldate.getCosttype1(), _summonpooldate.getCostid1(), _summonpooldate.getCostnum1() * num);
        if (new CurrencyHandle().costCheck(playerCode, cost1)) {
            costs.add(cost1);
        } else {
            long number1 = Currency.number(playerCode, cost1.getType(), cost1.getDataId(), false);
            long costNum = number1 / _summonpooldate.getCostnum1();
            // 补充消费
            Currency cost2 = Currency.create(_summonpooldate.getCosttype1(), _summonpooldate.getCostid1(), _summonpooldate.getCostnum1() * costNum);
            Currency cost3 = Currency.create(_summonpooldate.getCosttype2(), _summonpooldate.getCostid2(), _summonpooldate.getCostnum2() * (num - costNum));

            if (cost2 != null && cost2.getNumber() > 0) {
                costs.add(cost2);
            }
            if (cost3 != null && cost3.getNumber() > 0) {
                costs.add(cost3);
            }
        }
        if (costs.size() <= 0) {
            costs.add(cost1);
        }

        try {
            new CurrencyHandle().cost(playerCode, CCReason.招募武将, costs);
        } catch (CurrencyNotEnoughException e) {
            return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
        }
        // 奖励
        Collection<Currency> rewards = Currency.create(_summonpooldate.getGettype(), _summonpooldate.getGetid(), _summonpooldate.getGetnum());
        try {
            for (Currency reward : rewards) {
                reward.setNumber(reward.getNumber() * num);
            }
            new CurrencyHandle().addCurrency(playerCode, CCReason.招募武将, rewards);
            response.addAllRewards(new CurrencyHandle().packItems(rewards));
        } catch (Exception e) {
        }
        return Result.Success;
    }

    public Set<HeroMessage.GachaInfo> gachaInfo(String playerCode) {
        Set<HeroMessage.GachaInfo> set = new HashSet<>();
        GachaHeroModule module = GachaHeroModule.get(playerCode);

        //兼容：如果积分的没初始化，就初始化
        GachaHeroBean bean = module.bean(GachaHeroType.积分);
        summonpooldate data = DataCenter.getData(4, summonpooldate.class);
        if (bean == null) {
            GachaHeroBean gachaHeroBean = new GachaHeroBean();
            gachaHeroBean.setDataId(data.getId());
            gachaHeroBean.setGachaType(GachaHeroType.forNumber(data.getId()));
            gachaHeroBean.setFreeTimes(data.getFreenum());
            gachaHeroBean.setPointsResetTime(DateTime.now().withDayOfWeek(1).withTimeAtStartOfDay());
            gachaHeroBean.setUpdateTime(DateTime.now());//当前星期的周一
            gachaHeroBean.setTimes(0);
            bean = gachaHeroBean;
            module.getGachaList().add(gachaHeroBean);
            module.set();
        }

        //因为savetoDB没有重新部署，导致的pointsResetTime字段没有保存到数据库，进行兼容处理
        if (bean.getPointsResetTime() == null) {
            bean.setPointsResetTime(DateTime.now().withDayOfWeek(1).withTimeAtStartOfDay());
            module.set();
        }

        //判断每周一积分的消耗规则重置
        GachaHeroBean gachaHeroBean = module.bean(GachaHeroType.积分);
        DateTime nextResetTime = gachaHeroBean.getPointsResetTime().plusWeeks(1);
        DateTime nowTime = DateTime.now();//当前时间
        if (nowTime.isAfter(nextResetTime)) {
            gachaHeroBean.setDataId(data.getId());
            gachaHeroBean.setPointsResetTime(DateTime.now().withDayOfWeek(1).withTimeAtStartOfDay());//当前星期的周一
            gachaHeroBean.setTimes(0);
            module.set();
        }

        for (GachaHeroBean returnBean : module.getGachaList()) {
            set.add(gachaInfo(returnBean));
        }

        return set;
    }

    private HeroMessage.GachaInfo gachaInfo(GachaHeroBean bean) {
        HeroMessage.GachaInfo.Builder builder = HeroMessage.GachaInfo.newBuilder();
        builder.setDataId(bean.getDataId());
        builder.setType(bean.getGachaType().getNumber());
        builder.setFreeTimes(bean.getFreeTimes());
        if (bean.getFreeTimes() <= 0) {
            builder.setResetTime(bean.resetTime());
        }
        summonpooldate data = bean.data();
        if (data.getMusthit() > 0) {
            builder.setBingoTimes(data.getMusthit() - bean.getTimes());
        }
        return builder.build();
    }


    /**
     * 抽武将测试概率
     */
    public JSONObject summonHeroForTest(int num) {

        RBucket<Integer> summonHeroForTest = RedisManager.getInstance().getConnection(RedisType.REDIS_DATA).client().getBucket("summonHeroForTest");
        summonHeroForTest.set(0);


        //元宝抽奖
        GachaHeroType type = GachaHeroType.forNumber(2);

        JSONObject returnJson = new JSONObject();

        //保底的武将
        HashMap<Integer, Integer> map1 = new HashMap<>();        //区域  以及对应的数量
        HashMap<Integer, Integer> map2 = new HashMap<>();        //区域  以及对应的数量
        map2.put(113, 0);
        map2.put(114, 0);
        map2.put(115, 0);
        map2.put(116, 0);
        // 必得5星将(从id:113,114,115,116)中获取一位
        List<SummonData> list = new ArrayList<>();
        int idList[] = new int[]{113, 114, 115, 116};
        for (int y = 0; y < idList.length; y++) {
            summonpool data = DataCenter.getData(idList[y], summonpool.class);
            list.add(new SummonData(data));
        }

        for (int i = 0; i < num; i++) {
            SummonData mustGetOne = null;
            Reward reward = null;
            //30连保底20资质以上
            int aptitude = 0;
            if (summonHeroForTest.get() >= 2) {
                while (aptitude < 20) {
                    mustGetOne = RandomUtility.randomWeight(list);
                    reward = mustGetOne.getReward();
                    herodata data = DataCenter.getData(reward.id, herodata.class);
                    aptitude = data.getAptitude();//资质
                }
                //重置
                summonHeroForTest.set(0);
            } else {
                mustGetOne = RandomUtility.randomWeight(list);
                reward = mustGetOne.getReward();
                herodata data = DataCenter.getData(reward.id, herodata.class);
                aptitude = data.getAptitude();//资质
                //重置
                if (aptitude >= 20) {
                    summonHeroForTest.set(0);
                } else {
                    summonHeroForTest.set(summonHeroForTest.get() + 1);
                }
            }


            //存在就++ 否则则为1
            if (map1.containsKey(reward.id)) {
                Integer integer = map1.get(reward.id);
                integer++;
                map1.put(reward.id, integer);
            } else {
                map1.put(reward.id, 1);
            }

            //记录武将数量
            if (map2.containsKey(mustGetOne.data.id)) {
                Integer integer = map2.get(mustGetOne.data.id);
                integer++;
                map2.put(mustGetOne.data.id, integer);
            }

        }


        //元宝的全部武将区域
        Map<String, summonpool> datas = DataCenter.getAllData(summonpool.class);
        List<SummonData> list2 = new ArrayList<>();
        for (summonpool data : datas.values()) {
            if (data.getType() == type.getNumber()) {
                list2.add(new SummonData(data));
            }
        }


        HashMap<Integer, Integer> map3 = new HashMap<>();        //区域  以及对应的数量
        HashMap<Integer, Integer> map4 = new HashMap<>();        //区域  以及对应的数量
        map4.put(111, 0);
        map4.put(112, 0);
        map4.put(113, 0);
        map4.put(114, 0);
        map4.put(115, 0);
        map4.put(116, 0);
        //num 次10连抽
        for (int y = 0; y < num; y++) {
            int fiveHeroStarNum = 0;//抽中的五星武将   限制最多 2个
            List<Integer> fiveHeroList = Arrays.asList(113, 114, 115, 116);//5星卡池
            for (int i = 0; i < 9; i++) {
                SummonData one = RandomUtility.randomWeight(list2);
                while (fiveHeroList.contains(one.data.getId())) {
                    if (fiveHeroStarNum < 2) {
                        fiveHeroStarNum++;
                        break;
                    }
                    one = RandomUtility.randomWeight(list2);
                }
                Reward reward = one.getReward();

                //存在就++ 否则则为1
                if (map3.containsKey(reward.id)) {
                    Integer integer = map3.get(reward.id);
                    integer++;
                    map3.put(reward.id, integer);
                } else {
                    map3.put(reward.id, 1);
                }

                //记录武将数量
                if (map4.containsKey(one.data.id)) {
                    Integer integer = map4.get(one.data.id);
                    integer++;
                    map4.put(one.data.id, integer);
                }
            }

        }


        returnJson.put("map1", map1);
        returnJson.put("map2", map2);
        returnJson.put("map3", map3);
        returnJson.put("map4", map4);
        return returnJson;
    }

    /**
     * 抽武将
     */
    public Result summonHero(GachaHeroModule module, GachaHeroType type, int times, HeroMessage.GachaHeroResponse.Builder response) throws Exception {
        String playerCode = module.getPlayerCode();

        int num = times;
        if (type.equals(GachaHeroType.积分)) {
            int vip = fomula.积分招募VIP限制等级.intValue();
            PlayerBean playerBean = PlayerBean.get(playerCode);
            if (playerBean.getViplevel() < vip) {
                return Result.NoViplv;
            }
            num = 1;
        }

        Result result = summonCost(module, type, num, response);
        if (result != Result.Success) {
            return result;
        }

        Set<Hero> heros = new HashSet<>();
        if (type.equals(GachaHeroType.积分)) {
            return Result.Success;
        }

        //10连抽的保底武将处理
        num = floorsDispose(module, type, num, playerCode, heros);

        //获取十连抽的除保底的武将情况
        getRemainderHeros(type, num, playerCode, heros);

        //异步处理统计
        ThreadPoolManager.getInstance().execute(() -> {
            TaskHandle.handle(playerCode, TaskType.统计型_招募_次数, times);
            TaskHandle.handle(playerCode, TaskType.统计型_招募_次数, times, type.getNumber());
        });

        // 封装消息
        HeroHandle herosModule = new HeroHandle();
        for (Hero hero : heros) {
            response.addHeros(herosModule.getHeroSimple(playerCode, hero));
            HeroStarPublisher.getInstance().publish(playerCode, CCReason.招募武将, hero);
        }
        response.addAllInfo(gachaInfo(playerCode));

        return Result.Success;
    }

    /**
     * 保底的英雄处理
     *
     * @param module
     * @param type
     * @param num
     * @param playerCode
     * @param heros
     * @return
     */
    private int floorsDispose(GachaHeroModule module, GachaHeroType type, int num, String playerCode, Set<Hero> heros) {
        GachaHeroBean bean = module.bean(type);
        boolean bingo = false;// 必出
        boolean bingoForThirty = false;// 30必出资质20以上的武将
        if (bean == null) return num;
        //抽武将的表
        summonpooldate data = bean.data();
        //判断是否下一抽是必中
        if (data.getMusthit() > 0 && (bean.getTimes() + num >= data.getMusthit())) {
            bingo = true;
            bean.setTimes(bean.getTimes() + num - data.getMusthit());
        }
        //不是必中则增加次数，到10的时候下一抽必中
        if (data.getMusthit() > 0 && !bingo) {
            bean.setTimes(bean.getTimes() + num);
        }
        //控制30抽保底20资质以上
        bean.setThirtyTimes(bean.getThirtyTimes() + num);
        //当30连抽还是没出资质20以上就保底的武将变成资质20以上
        if (bean.getThirtyTimes() >= 30) {
            bingoForThirty = true;
        }
        module.set();

        //保底获取,30连还没出资质20的保底就出资质20以上武将
        if (bingo) {

//            //前两次保底处理，每个人仅限一次(第一次20资质，第二次正常走，第三次21资质，后面都正常走)
//            if (bean.getTimesForMusthit() == 0 || bean.getTimesForMusthit() == 2) {
//                returnTimesForMusthi(playerCode, heros, bean, module, bean.getTimesForMusthit());
//                num -= 1;
//                return num;
//            }
//
//            if(bean.getTimesForMusthit() == 1){
//                bean.setTimesForMusthit(2);
//            }

            //30次十连的20资质以上保底
            if (bingoForThirty) {
                returnThirtyTimesMustHitHero(playerCode, heros, bean, module);
            }
            //保底获取,10连的普通保底
            if (!bingoForThirty) {
                returnTenthTimesMustHitHero(playerCode, heros, bean, module);
            }
            num -= 1;
        }
        return num;
    }

    //前两次保底处理，每个人仅限一次
    private void returnTimesForMusthi(String playerCode, Set<Hero> heros, GachaHeroBean bean, GachaHeroModule module, int timesForMusthit) {

        //必出20资质
        if (timesForMusthit == 0) {
            bean.setTimesForMusthit(1);
            returnMustHit_X_AptitudeHero(playerCode, heros, bean, module, 20);
            return;
        }

        //必出21资质
        if (timesForMusthit == 2) {
            bean.setTimesForMusthit(3);
            returnMustHit_X_AptitudeHero(playerCode, heros, bean, module, 21);
            return;
        }

    }

    /**
     * 必得X资质
     *
     * @param playerCode
     * @param heros
     * @param bean
     * @param module
     * @param x
     */
    private void returnMustHit_X_AptitudeHero(String playerCode, Set<Hero> heros, GachaHeroBean bean, GachaHeroModule module, int x) {
        // 必得5星将(从id:113,114,115,116)中获取一位
        List<SummonData> list = new ArrayList<>();
        int idList[] = new int[]{113, 114, 115, 116};
        for (int i = 0; i < idList.length; i++) {
            summonpool data = DataCenter.getData(idList[i], summonpool.class);
            list.add(new SummonData(data));
        }

        int heroId = 0;
        int aptitude = 0;
        while (aptitude != x) {
            SummonData mustGetOne = RandomUtility.randomWeight(list);
            Reward reward = mustGetOne.getReward();
            herodata data = DataCenter.getData(reward.id, herodata.class);
            aptitude = data.getAptitude();//资质
            heroId = reward.id;
        }
        Hero hero = new HeroHandle().createHero(playerCode, heroId, CCReason.招募武将);
        if (hero != null) {
            heros.add(hero);
        }
        //记录抽出的武将
        module.set();
    }


    /**
     * 计算除保底后的武将
     *
     * @param type
     * @param num
     * @param playerCode
     * @param heros
     */
    private void getRemainderHeros(GachaHeroType type, int num, String playerCode, Set<Hero> heros) {
        // 测试抽将
        Map<String, summonpool> datas = DataCenter.getAllData(summonpool.class);
        List<SummonData> list = new ArrayList<>();
        for (summonpool data : datas.values()) {
            if (data.getType() == type.getNumber()) {
                list.add(new SummonData(data));
            }
        }

//        HashMap<Integer, JSONArray> heroInfo = new HashMap<>();   //展示抽出的武将和卡池位置
        int fiveHeroStarNum = 0;//抽中的五星武将   限制最多 2个
        List<Integer> fiveHeroList = Arrays.asList(113, 114, 115, 116);//5星卡池

        for (int i = 0; i < num; i++) {

            SummonData one = RandomUtility.randomWeight(list);
            while (fiveHeroList.contains(one.data.getId())) {
                if (fiveHeroStarNum < 2) {
                    fiveHeroStarNum++;
                    break;
                }
                one = RandomUtility.randomWeight(list);
            }

            boolean is暴击 = RandomUtility.ppm() < one.data.probability;
            Reward reward = one.getReward();

            Hero hero = new HeroHandle().createHero(playerCode, reward.id, CCReason.招募武将);
            if (hero != null) {
                heros.add(hero);
            }
            if (is暴击) {
                hero = new HeroHandle().createHero(playerCode, reward.id, CCReason.招募武将);
                if (hero != null) {
                    heros.add(hero);
                }
            }
//            JSONArray jsonArray = new JSONArray();
//            jsonArray.add(reward.id);
//            jsonArray.add(one.data.id);
//            heroInfo.put(i, jsonArray);
        }
        //记录抽出的武将
//        Battle.battleLogger(1, "--------------------------------抽取到的武将-----------------------------------" + heroInfo);
    }

    /**
     * 30连抽保底的20资质武将
     *
     * @param playerCode
     * @param heros
     * @param bean
     * @param module
     */
    private void returnThirtyTimesMustHitHero(String playerCode, Set<Hero> heros, GachaHeroBean bean, GachaHeroModule module) {

        // 必得5星将(从id:113,114,115,116)中获取一位
        int heroId = 0;
        int group = 0;
        int aptitude = 0;
        while (aptitude < 20) {
            List<SummonData> list = new ArrayList<>();
            int idList[] = new int[]{113, 114, 115, 116};
            for (int i = 0; i < idList.length; i++) {
                summonpool data = DataCenter.getData(idList[i], summonpool.class);
                list.add(new SummonData(data));
            }
            SummonData mustGetOne = RandomUtility.randomWeight(list);
            Reward reward = mustGetOne.getReward();
            herodata data = DataCenter.getData(reward.id, herodata.class);
            aptitude = data.getAptitude();//资质
            heroId = reward.id;
            group = mustGetOne.data.id;
        }
        Hero hero = new HeroHandle().createHero(playerCode, heroId, CCReason.招募武将);
        if (hero != null) {
            heros.add(hero);
        }
        //记录抽出的武将
        Battle.battleLogger(1, "30连必中的资质20以上武将所属位置和id:::::" + heroId + ":::::" + group + ":::::资质:::::" + aptitude);
        bean.setThirtyTimes(0);
        module.set();
    }

    /**
     * 10连抽保底
     *
     * @param playerCode
     * @param heros
     * @param bean
     * @param module
     */
    private void returnTenthTimesMustHitHero(String playerCode, Set<Hero> heros, GachaHeroBean bean, GachaHeroModule module) {
        // 必得5星将(从id:113,114,115,116)中获取一位
        List<SummonData> list = new ArrayList<>();
        int idList[] = new int[]{113, 114, 115, 116};
        for (int i = 0; i < idList.length; i++) {
            summonpool data = DataCenter.getData(idList[i], summonpool.class);
            list.add(new SummonData(data));
        }
        SummonData mustGetOne = RandomUtility.randomWeight(list);
        Reward reward = mustGetOne.getReward();
        Hero hero = new HeroHandle().createHero(playerCode, reward.id, CCReason.招募武将);
        if (hero != null) {
            heros.add(hero);
        }

        //如果抽出资质20以上的武将就重置30连抽必出资质20武将的次数
        herodata data = DataCenter.getData(reward.id, herodata.class);
        if (data.getAptitude() >= 20) {
            bean.setThirtyTimes(0);
            module.set();
        }

        //记录抽出的武将
        Battle.battleLogger(1, "10连必中的武将所属位置和id:::::" + reward.id + ":::::" + mustGetOne.data.id + ":::::资质:::::" + data.getAptitude());
    }

    /**
     * 消耗
     *
     * @param module
     * @param type
     * @param num
     * @param response
     * @return
     */
    private Result summonCost(GachaHeroModule module, GachaHeroType type, int num, HeroMessage.GachaHeroResponse.Builder response) {

        String playerCode = module.getPlayerCode();

        GachaHeroBean bean = module.bean(type);

        // 抽将付费
        summonpooldate _summonpooldate = type.equals(GachaHeroType.积分) ? DataCenter.getData(bean.getDataId(), summonpooldate.class) : DataCenter.getData(type.getNumber(), summonpooldate.class);

        if (num == 1) {
            if (bean != null) {
                if (bean.getFreeTimes() > 0) {
                    bean.freeonce();
                    module.set();
                    return Result.Success;
                }
            }
        }

        // 优先消费
        ArrayList<Currency> costs = new ArrayList<>();
        Currency cost1 = Currency.create(_summonpooldate.getCosttype1(), _summonpooldate.getCostid1(), _summonpooldate.getCostnum1() * num);
        if (new CurrencyHandle().costCheck(playerCode, cost1)) {
            costs.add(cost1);
        } else {
            long number1 = Currency.number(playerCode, cost1.getType(), cost1.getDataId(), false);
            long costNum = number1 / _summonpooldate.getCostnum1();
            // 补充消费
            Currency cost2 = Currency.create(_summonpooldate.getCosttype1(), _summonpooldate.getCostid1(), _summonpooldate.getCostnum1() * costNum);
            Currency cost3 = Currency.create(_summonpooldate.getCosttype2(), _summonpooldate.getCostid2(), _summonpooldate.getCostnum2() * (num - costNum));

            if (cost3 == null) {
                costs.add(cost1);
            } else {
                if (cost2 != null && cost2.getNumber() > 0) {
                    costs.add(cost2);
                }
                if (cost3 != null && cost3.getNumber() > 0) {
                    costs.add(cost3);
                }
            }
        }
        if (costs.size() <= 0) {
            costs.add(cost1);
        }

        try {
            new CurrencyHandle().cost(playerCode, CCReason.招募武将, costs);
        } catch (CurrencyNotEnoughException e) {
            return new Result(Result.CostFail, e.getType().getNumber(), e.getDataId());// 消费不足
        }
        // 奖励(2022.8.17 奖励修改为333服后面的跟前面的奖励不同) 仅限积分兑换
        ArrayList<Currency> rewards = new ArrayList<>();
        config data = DataCenter.getData(1, config.class);
        PlayerBean playerBean = PlayerBean.get(playerCode);
        JSONObject jsonObject = JSONObject.parseObject(data.getValue());
        Boolean isNewServer = playerBean.getServerId() >= jsonObject.getInteger("begin_server");
        if (type.equals(GachaHeroType.积分) && isNewServer) {
            Currency currency = Currency.create(jsonObject.getInteger("gettype"), jsonObject.getInteger("getid"), jsonObject.getInteger("getnum"));
            Currency currency2 = Currency.create(_summonpooldate.getGettype()[1], _summonpooldate.getGetid()[1], _summonpooldate.getGetnum()[1]);
            rewards.add(currency);
            rewards.add(currency2);

        } else {
            Collection<Currency> currencies = Currency.create(_summonpooldate.getGettype(), _summonpooldate.getGetid(), _summonpooldate.getGetnum());
            rewards.addAll(currencies);
        }

        try {
            for (Currency reward : rewards) {
                reward.setNumber(reward.getNumber() * num);
            }
            new CurrencyHandle().addCurrency(playerCode, CCReason.招募武将, rewards);
            response.addAllRewards(new CurrencyHandle().packItems(rewards));
        } catch (Exception e) {
        }

        //如果是积分兑换，相应改缓存
        if (type.equals(GachaHeroType.积分) && bean.getTimes() < 4) {
            bean.setTimes(bean.getTimes() + 1);
            bean.setDataId(bean.getDataId() + 1);
            module.set();
        }

        return Result.Success;
    }

    private class SummonData implements Weight {
        private summonpool data;

        private SummonData(summonpool data) {
            this.data = data;
        }

        private Reward getReward() {
            List<Reward> rewards = new ArrayList<>();
            for (int i = 0; i < data.getRewardid().length; i++) {
                int id = data.getRewardid()[i];
                int weight = data.getPercent()[i];
                if (id > 0 && weight > 0) {
                    rewards.add(new Reward(id, weight));
                }
            }
            return RandomUtility.randomWeight(rewards);
        }

        @Override
        public int getWeight() {
            return data.getWeight();
        }
    }

    private class Reward implements Weight {

        int id;
        int weight;

        private Reward(int id, int weight) {
            this.id = id;
            this.weight = weight;
        }

        @Override
        public int getWeight() {
            return weight;
        }
    }
}
